package org.zxt.web.context.handler.parser;

import com.alibaba.fastjson.JSON;
import org.zxt.web.context.WebContext;
import org.zxt.web.context.annotation.RequestBody;
import org.zxt.web.context.handler.ArgumentParser;
import org.zxt.web.nio.BodyBufferedInputStream;
import org.zxt.web.nio.IHTTPSession;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Parameter;
import java.nio.ByteBuffer;
import java.util.*;

public class RequestBodyParser implements ArgumentParser {
    public boolean support(Parameter p){
        return p.getAnnotation(RequestBody.class) != null;
    }
    @Override
    public Object parse(Parameter p, WebContext webContext, IHTTPSession session) {
        try {
            int total = Integer.parseInt(session.getHeaders().get("content-length"));
            BodyBufferedInputStream bufferedInputStream = session.getBody();
            ByteBuffer byteBuffer = ByteBuffer.allocate(8*4096);
            byte[] bs = new byte[total];
            int sum = 0;
            while (sum != total){
                int len = bufferedInputStream.readIn(byteBuffer);
                byteBuffer.flip();
                if(len > 0) {
                    System.arraycopy(byteBuffer.array(), 0, bs, sum, len);
                    sum += len;
                }
                byteBuffer.clear();
            }
            if(p.getType() == String.class){
                return new String(bs);
            } else if(p.getType() == byte[].class) {
                return bs;
            }
            if(session.getHeaders().get("content-type").startsWith("application/json")){
                return JSON.parseObject(bs, p.getType());
            } else {
                throw new Exception("not support content-type:"+session.getHeaders().get("content-type"));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
